package site.teamo.biu.flink.web.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import site.teamo.biu.flink.common.function.descriptor.OperatorParameterDescriptor;
import site.teamo.biu.flink.web.controller.model.BiuJSONResult;
import site.teamo.biu.flink.web.controller.model.function.ListGroupByPackageResponse;
import site.teamo.biu.flink.web.entity.OperatorDO;
import site.teamo.biu.flink.web.entity.OperatorPackageDO;
import site.teamo.biu.flink.web.service.OperatorPackageService;
import site.teamo.biu.flink.web.service.OperatorService;
import site.teamo.biu.flink.web.util.BiuJSONResultUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author haocongshun
 * @date 2023/11/06 11:14:12
 */
@Api(tags = "算子信息")
@RestController
@RequestMapping("/api/operator")
public class OperatorController {

    @Resource(name = "operatorServiceImpl")
    private OperatorService operatorService;

    @Resource(name = "operatorPackageServiceImpl")
    private OperatorPackageService operatorPackageService;

    @GetMapping("/list-group-by-package")
    public BiuJSONResult listGroupByPackage(@RequestParam(required = false) String keyword,
                                            @RequestParam String type) {
        ListGroupByPackageResponse response = new ListGroupByPackageResponse();
        List<OperatorDO> list = operatorService.list(keyword, type);
        if (CollectionUtil.isEmpty(list)) {
            return BiuJSONResultUtils.ok(response);
        }
        Map<String, List<OperatorDO>> map = list.stream()
                .collect(Collectors.groupingBy(OperatorDO::getOperatorPackageId));
        Map<String, OperatorPackageDO> functionPackageDOMap = operatorPackageService.listByIds(map.keySet())
                .stream()
                .collect(Collectors.toMap(OperatorPackageDO::getId, Function.identity()));
        for (Map.Entry<String, List<OperatorDO>> entry : map.entrySet()) {
            OperatorPackageDO functionPackageDO = functionPackageDOMap.get(entry.getKey());
            response.add(new ListGroupByPackageResponse.Element()
                    .setId(functionPackageDO.getId())
                    .setName(functionPackageDO.getName())
                    .setTag(functionPackageDO.getTag())
                    .setFunctions(entry.getValue().stream()
                            .map(f -> new ListGroupByPackageResponse.Element.Item()
                                    .setId(f.getId())
                                    .setName(f.getName())
                                    .setType(f.getType())
                                    .setClassName(f.getClassName())
                                    .setParameters(OperatorParameterDescriptor.generateList(JSON.parseArray(f.getParameters(), JSONObject.class))))
                            .collect(Collectors.toList()))
            );
        }
        return BiuJSONResultUtils.ok(response);
    }

}
